package com.xjj.service.controller;

import com.anji.captcha.model.vo.CaptchaVO;
import com.anji.captcha.service.CaptchaService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.xjj.entity.Manager;
import com.xjj.entity.ResponseEntity;
import com.xjj.service.feign.ManagerFeignClient;
import com.xjj.util.exception.CaptchaException;
import com.xjj.util.exception.ManagerExistsException;
import com.xjj.util.exception.PasswordException;
import com.xjj.util.utils.JwtUtil;
import com.xjj.vo.ManagerLoginVO;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;

import static com.xjj.util.utils.RedisConstants.*;

/**
 * @author : 王泰元
 * @date : 2022/10/20 15:55
 */
@Api(tags = "管理员登录接口")
@RestController
@RequestMapping("/auth/admin")
@Slf4j
public class ManagerLoginController {
    @Resource
    ManagerFeignClient managerFeignClient;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    @Lazy
    private CaptchaService captchaService;

    @ApiOperation("管理员登录")
    @PostMapping("/login")
    public ResponseEntity<Manager> login(@RequestBody ManagerLoginVO loginVO, HttpServletResponse response) throws JsonProcessingException {

        //  图片验证码二次校验
        CaptchaVO captchaVO = new CaptchaVO();
        captchaVO.setCaptchaVerification(loginVO.getCaptcha());
        if (!captchaService.verification(captchaVO).isSuccess()) {
            throw new CaptchaException("验证失败，请稍后再试");
        }

        // 登录用户 loginVoManager
        Manager loginVoManager = loginVO.getManager();

        // 远程调用微服务 manage，根据账号获取用户 manager
        Manager manager = managerFeignClient.getByAccount(loginVO.getManager().getAccount()).getData();

        // 账号不存在
        if (manager == null) {
            throw new ManagerExistsException("账户不存在");
        }

        // 密码加密比对
        loginVoManager.setPassword(DigestUtils.md5Hex(loginVoManager.getPassword()));
        if (!loginVoManager.getPassword().equals(manager.getPassword())) {
            throw new PasswordException("密码不正确");
        }

        // 生成 jwt
        manager.setPassword(null);
        String token = JwtUtil.createToken(new ObjectMapper().writeValueAsString(manager), "manager");
        // token 存到 redis ，有效期 30m
        redisTemplate.opsForValue().set(LOGIN_TOKEN_ADMIN_KEY + manager.getId(), manager, LOGIN_TOKEN_TTL, TimeUnit.MINUTES);

        response.setHeader("token", token);

        response.setHeader("Access-Control-Expose-Headers", "*");

        return ResponseEntity.SUCCESS("登录成功", manager);
    }

    @ApiOperation("获取当前登陆用户信息")
    @GetMapping("/getMe")
    public ResponseEntity<Manager> getMe(HttpServletRequest request) throws JsonProcessingException {
        return ResponseEntity.SUCCESS("ok", JwtUtil.getManager(request.getHeader("token")));
    }

    @GetMapping("/logout")
    @ApiOperation("手动登录白名单实现")
    public ResponseEntity logout(HttpServletRequest request) throws JsonProcessingException {
        Manager manager = JwtUtil.getManager(request.getHeader("token"));
        String token = request.getHeader("token");
        redisTemplate.opsForValue().set(manager.getAccount() + ":untoken", token, 30, TimeUnit.MINUTES);
        return ResponseEntity.SUCCESS("操作成功", null);
    }
}
